﻿using System;
using System.Windows;
using theeg.GraphWpf.Models;

namespace theeg.GraphWpf.Arrangement
{
    internal static class CustomRouting
    {
        private static void CalculateEndpointOrientation(Transition transition)
        {
            Point source = new Point(transition.Source.CenterX, transition.Source.CenterY);
            Point target = new Point(transition.Target.CenterX, transition.Target.CenterY);

            double theta = Math.Atan2(source.Y - target.Y, target.X - source.X);
            if (theta < 0)
            {
                theta += 2 * Math.PI;
            }

            if (theta > 0.25 * Math.PI && theta <= 0.75 * Math.PI)
            {
                transition.SourceOrientation = ConnectorOrientation.Top;
                transition.TargetOrientation = ConnectorOrientation.Bottom;
            }
            else if (theta > 0.75 * Math.PI && theta <= 1.25 * Math.PI)
            {
                transition.SourceOrientation = ConnectorOrientation.Left;
                transition.TargetOrientation = ConnectorOrientation.Right;
            }
            else if (theta > 1.25 * Math.PI && theta <= 1.75 * Math.PI)
            {
                transition.SourceOrientation = ConnectorOrientation.Bottom;
                transition.TargetOrientation = ConnectorOrientation.Top;
            }
            else
            {
                transition.SourceOrientation = ConnectorOrientation.Right;
                transition.TargetOrientation = ConnectorOrientation.Left;
            }
            transition.RoutingPoints.Add(RoutingMediator.OrientationToEndpoint(transition.SourceOrientation, transition.Source));
            transition.RoutingPoints.Add(RoutingMediator.OrientationToEndpoint(transition.TargetOrientation, transition.Target));
        }

        private static void CalculateEndpointOrientationStrict(Transition transition)
        {
            Point source = new Point(transition.Source.CenterX, transition.Source.CenterY);
            Point target = new Point(transition.Target.CenterX, transition.Target.CenterY);

            if (transition.RoutingStyle == RoutingStyle.FreeHandHorizontal)
            {
                if (source.X < target.X)
                {
                    transition.SourceOrientation = ConnectorOrientation.Right;
                    transition.TargetOrientation = ConnectorOrientation.Left;                   
                }else if (source.X > target.X)
                {
                    transition.SourceOrientation = ConnectorOrientation.Left;
                    transition.TargetOrientation = ConnectorOrientation.Right;                   
                }
                else
                {
                    transition.SourceOrientation = ConnectorOrientation.Right;
                    transition.TargetOrientation = ConnectorOrientation.Right;                  
                }
            }
            else
            {
                if (source.Y < target.Y)
                {
                    transition.SourceOrientation = ConnectorOrientation.Bottom;
                    transition.TargetOrientation = ConnectorOrientation.Top;
                }
                else if (source.Y > target.Y)
                {
                    transition.SourceOrientation = ConnectorOrientation.Top;
                    transition.TargetOrientation = ConnectorOrientation.Bottom;
                }
                else
                {
                    transition.SourceOrientation = ConnectorOrientation.Bottom;
                    transition.TargetOrientation = ConnectorOrientation.Bottom;
                }              
            }
            transition.RoutingPoints.Add(RoutingMediator.OrientationToEndpoint(transition.SourceOrientation, transition.Source));
            transition.RoutingPoints.Add(RoutingMediator.OrientationToEndpoint(transition.TargetOrientation, transition.Target));
        }

        internal static void CalculateRoutingPoints(Transition transition)
        {
            transition.RoutingPoints.Clear();
            if (transition.RoutingStyle == RoutingStyle.FreeHand)
            {
                CalculateEndpointOrientation(transition);
            }
            else
            {
                CalculateEndpointOrientationStrict(transition);
            }
            transition.RoutingPoints.InsertRange(1, transition.ControlPoints);
        }
    }
}
